package com.bc.bccore.redis;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.util.Set;
import java.util.concurrent.TimeUnit;

@Service
public class RedisService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    private ValueOperations<String, Object> getOperation() {
        return redisTemplate.opsForValue();
    }

    /**
     * redis存储，永久有效,当前RedisService为了和.net程序互通，value只支持string
     *
     * @param key   key
     * @param value value
     */
    public void set(String key, String value) {
        try {
            ValueOperations<String, Object> operation = getOperation();
            operation.set(suffxKey(key), value);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * redis存储方法,当前RedisService为了和.net程序互通，value只支持string
     *
     * @param key     key
     * @param value   value
     * @param timeout 过期时间，单位默认为秒，
     */
    public void set(String key, String value, long timeout) {
        set(key, value, timeout, TimeUnit.SECONDS);
    }

    /**
     * redis存储,当前RedisService为了和.net程序互通，value只支持string
     *
     * @param key      redis key
     * @param value    redis value
     * @param timeout  过期时间
     * @param timeUnit 过期时间单位
     */
    public void set(String key, String value, long timeout, TimeUnit timeUnit) {
        try {
            ValueOperations<String, Object> operation = getOperation();
            operation.set(suffxKey(key), value, timeout, timeUnit);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 生成一个锁
     */
    public boolean setnx(String key, String value) {
        try {
            ValueOperations<String, Object> operation = getOperation();
            return operation.setIfAbsent(suffxKey(key), value);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

    /**
     * 获取Redis值， isSuffxKey=false时不加redis版本及前缀,当前RedisService为了和.net程序互通，value只支持string
     */
    public String get(String key, Boolean isSuffxKey) {
        try {
            ValueOperations<String, Object> operation = getOperation();
            String finalKey = isSuffxKey ? suffxKey(key) : key;
            Object object = operation.get(finalKey);
            if (object != null) {
                return object.toString();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取Redis值， isSuffxKey=true+版本及前缀,当前RedisService为了和.net程序互通，value只支持string
     */
    public String get(String key) {
        return get(key, true);
    }

    public void remove(String keyPattern, Boolean isSuffxKey) {
        String finalKey = isSuffxKey ? suffxKey(keyPattern) : keyPattern;
        //Set<String> removeKeys = redisTemplate.keys(finalKey);
        redisTemplate.delete(finalKey);
    }

    public void remove(String keyPattern) {
        remove(keyPattern, true);
		/*Set<String> removeKeys = redisTemplate.keys(suffxKey(keyPattern));
		redisTemplate.delete(removeKeys);*/
    }

    /**
     * 获取所有相似key
     *
     * @param keyPattern 模糊键
     * @author haichao
     * @date 2015年9月29日 13:10:05
     */
    public Set<String> keys(String keyPattern) {
        return redisTemplate.keys("*" + keyPattern + "*");
    }

    /**
     * 给key添加后缀或前缀
     *
     * @param orginKey
     * @return
     * @author hailongzhao
     * @date 20150902
     */
    private String suffxKey(String orginKey) {
        //return "java_tools_" + PropertyUtils.getProperty("GlobalVersion") + "_"+ orginKey;
        return orginKey;
    }

    public void hset(String key, String field, String value) {
        redisTemplate.opsForHash().put(key, field, value);
    }

    public String hget(String key, String field) {
        Object ret = redisTemplate.opsForHash().get(key, field);
        if (ret != null) {
            return ret.toString();
        }
        return null;
    }

}
